package net.sf.jimex.jira;

import com.atlassian.jira.config.SubTaskManager;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.IssueUtilsBean;
import com.atlassian.jira.issue.IssueFactory;
import com.atlassian.jira.issue.fields.AffectedVersionsSystemField;
import com.atlassian.jira.issue.fields.ComponentsSystemField;
import com.atlassian.jira.issue.fields.FixVersionsSystemField;
import com.atlassian.jira.issue.fields.PrioritySystemField;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.jira.security.JiraAuthenticationContext;

import java.util.HashMap;
import java.util.Map;

/**
 * andrew 16.03.2006 0:01:56
 */
public class JiraIssuesManagerImpl extends AbstractJiraIssuesManager  {
    private JimexJiraIssuesManager issuesManager;
    private Map issuesManagerMap = new HashMap();

    public JiraIssuesManagerImpl(IssueUtilsBean issueUtilsBean, IssueManager issueManager, ProjectManager projectManager, JiraAuthenticationContext authenticationContext, SubTaskManager subTaskManager, IssueFactory issueFactory) {
        super(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory);
        issuesManagerMap.put(LinkType.TYPE_NONE, new TypeNoneIssuesManager(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory));
        if (subTaskManager.isSubTasksEnabled()) {
            issuesManagerMap.put(LinkType.TYPE_SUBTASK, new SubTasksIssuesManager(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory));
            issuesManagerMap.put(LinkType.TYPE_SUBTASK_LAST, new SubTaskLeafIssuesManager(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory));
        }
    }

    public void setProjectId(Long projectId) {
        issuesManager.setProjectId(projectId);
    }

    public void setComponents(ComponentsSystemField componentsSystemField) {
        issuesManager.setComponents(componentsSystemField);
    }

    public void setAffectedVersions(AffectedVersionsSystemField affectedVersionsSystemField) {
        issuesManager.setAffectedVersions(affectedVersionsSystemField);
    }

    public void setFixVersions(FixVersionsSystemField fixVersionsSystemField) {
        issuesManager.setFixVersions(fixVersionsSystemField);
    }

    public void setPriority(PrioritySystemField prioritySystemField) {
        issuesManager.setPriority(prioritySystemField);
    }

    public void setCustomFieldValuesHolder(Map customFieldValuesHolder) {
        issuesManager.setCustomFieldValuesHolder(customFieldValuesHolder);
    }

    public void setIssueType(String issuetype) {
        issuesManager.setIssueType(issuetype);
    }

    public void setLinkType(Long linkType) {
        Object issuesManagerObject = issuesManagerMap.get(linkType);
        if (issuesManagerObject == null) {
            throw new IllegalArgumentException("Cann't found  issues manager for linkType:" + linkType);
        }
        issuesManager = (JimexJiraIssuesManager) issuesManagerObject;
    }



    public String createIssue(String summary, String description, String userName, String estimate, int issueType) throws Exception {
        return issuesManager.createIssue(summary, description, userName, estimate, issueType);
    }

    public String createChildIssue(String parentIssueKey, String title, String description, String assignee, String estimate, boolean hasSubTasks) throws Exception {
        return issuesManager.createChildIssue(parentIssueKey, title, description, assignee, estimate, hasSubTasks);
    }

    private static class TypeNoneIssuesManager extends AbstractJiraIssuesManager {
        public TypeNoneIssuesManager(IssueUtilsBean issueUtilsBean, IssueManager issueManager, ProjectManager projectManager, JiraAuthenticationContext authenticationContext, SubTaskManager subTaskManager, IssueFactory issueFactory) {
            super(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory);
        }

        public String createIssue(String summary, String description, String assignee, String estimate, int issueType) throws Exception {
            return createIssueInternal(summary, estimate, assignee, description, null, getIssuetype());
        }

        public String createChildIssue(String parentIssueKey, String summary, String description, String assignee, String estimate, boolean hasSubTasks) throws Exception {
            return createIssueInternal(summary, estimate, assignee, description, null, getIssuetype());
        }
    }

    private static class SubTasksIssuesManager extends AbstractJiraIssuesManager {
        public SubTasksIssuesManager(IssueUtilsBean issueUtilsBean, IssueManager issueManager, ProjectManager projectManager, JiraAuthenticationContext authenticationContext, SubTaskManager subTaskManager, IssueFactory issueFactory) {
            super(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory);
        }

        public String createIssue(String summary, String description, String assignee, String estimate, int issueType) throws Exception {
            return createIssueInternal(summary, estimate, assignee, description, null, getIssuetype());
        }

        public String createChildIssue(String parentIssueKey, String summary, String description, String assignee, String estimate, boolean hasSubTasks) throws Exception {
            return createIssueInternal(summary, estimate, assignee, description, parentIssueKey, IssueHelper.SUBTASK_TYPE);
        }
    }

    private static class SubTaskLeafIssuesManager extends AbstractJiraIssuesManager {
        public SubTaskLeafIssuesManager(IssueUtilsBean issueUtilsBean, IssueManager issueManager, ProjectManager projectManager, JiraAuthenticationContext authenticationContext, SubTaskManager subTaskManager, IssueFactory issueFactory) {
            super(issueUtilsBean, issueManager, projectManager, authenticationContext, subTaskManager, issueFactory);
        }

        public String createIssue(String summary, String description, String assignee, String estimate, int issueType) throws Exception {
            return createIssueInternal(summary, estimate, assignee, description, null, getIssuetype());
        }

        public String createChildIssue(String parentIssueKey, String summary, String description, String assignee, String estimate, boolean hasSubTasks) throws Exception {
            if (hasSubTasks) {
                return createIssueInternal(summary, estimate, assignee, description, null, getIssuetype());
            }
            return createIssueInternal(summary, estimate, assignee, description, parentIssueKey, IssueHelper.SUBTASK_TYPE);
        }
    }
}
